<template>
  <div class="shortcut-input">
    <el-input
      ref="inputRef"
      :model-value="displayValue"
      :placeholder="$t('settings.shortcutInput')"
      readonly
      @focus="startListening"
      @blur="stopListening"
      size="large"
    >
    </el-input>
    <el-icon class="clearable-btn" @click.stop="clearShortcut" v-if="displayValue"><CircleCloseFilled /></el-icon>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useI18n } from 'vue-i18n'
const { t } = useI18n({ useScope: 'global' })

const props = defineProps<{ modelValue?: string }>()
const emits = defineEmits<{
  (e: 'update:modelValue', value: string): void
}>()

const displayValue = ref(props.modelValue || '')

watch(() => props.modelValue, (val) => {
  if (val !== displayValue.value) displayValue.value = val || ''
})

const shortcutKeys = ref<string[]>([])
let listening = false
// 支持的修饰键
const modifierKeys = ['Ctrl', 'Alt', 'Shift', 'Meta']

const startListening = () => {
  if (listening) return
  listening = true
  window.addEventListener('keydown', handleKeydown)
  window.addEventListener('keyup', handleKeyup)
}

const stopListening = () => {
  if (!listening) return
  listening = false

  window.removeEventListener('keydown', handleKeydown)
  window.removeEventListener('keyup', handleKeyup)
  
  // 失去焦点的时候在检查一次
  if (shortcutKeys.value.length > 0) {
    const normalized = normalizeShortcut(shortcutKeys.value)
    if (!checkShortcut(normalized)) {
      ElMessage({ message: t('settings.shortcutInputWarn'), type: 'warning' })
      displayValue.value = ''
      emits('update:modelValue', displayValue.value)
    }
  }

  // 清空按键状态
  shortcutKeys.value = []
}

// 按下键时处理函数
const handleKeydown = (e: KeyboardEvent) => {
  e.preventDefault()
  let currentMainKey = ''

  // 判断 Ctrl / Alt / Shift / Meta (Command)
  if (e.key === 'Control') currentMainKey = 'Ctrl'
  else if (e.key === 'Alt') currentMainKey = 'Alt'
  else if (e.key === 'Shift') currentMainKey = 'Shift'
  else if (e.key === 'Meta') currentMainKey = 'Meta' // Mac ⌘ Command 键
  else if (/^Key[A-Z]$/.test(e.code)) currentMainKey = e.code.replace('Key', '').toUpperCase()
  else if (/^Digit[0-9]$/.test(e.code)) currentMainKey = e.code.replace('Digit', '')
  else if (/^Numpad[0-9]$/.test(e.code)) currentMainKey = e.code.replace('Numpad', '')
  else if (/^[a-zA-Z0-9]$/.test(e.key)) currentMainKey = e.key.toUpperCase()

  if (shortcutKeys.value.length === 0) {
    const hasModifier = modifierKeys.includes(currentMainKey)
    if (!hasModifier) {
      ElMessage({ message: t('settings.shortcutInputWarn'), type: 'warning', grouping: true, })
      return
    }
  }

  if (currentMainKey !== '' && !shortcutKeys.value.some(item => item === currentMainKey)) {
    shortcutKeys.value.push(currentMainKey)
    displayValue.value = shortcutKeys.value.join(' + ')
  }
}

// 松开键时处理函数
const handleKeyup = (e: KeyboardEvent) => {
  const normalized = normalizeShortcut(shortcutKeys.value)
  const lastKey = normalized[normalized.length - 1] // 最后一个按键

  if (lastKey && lastKey === normalizeKey(e)) {
    if (checkShortcut(normalized)) {
      displayValue.value = normalized.join(' + ')
      ElMessage({ message: t('settings.shortcutInputSuccess'), type: 'success', grouping: true, })
    } else {
      ElMessage({ message: t('settings.shortcutInputWarn'), type: 'warning', grouping: true, })
      displayValue.value = ''
    }
    
    // 松开后重置状态
    emits('update:modelValue', displayValue.value)
    shortcutKeys.value = []
  }
}

// 快捷键检测函数
const checkShortcut = (keys: string[]) => {
  if (!keys.length) return false

  // 至少一个修饰键开头
  const hasModifier = modifierKeys.includes(keys[0])
  if (!hasModifier) return false

  if (keys.length === 2 && keys[0] === 'Shift') return false

  // 最后一个必须是字母或数字
  const lastKey = keys[keys.length - 1]
  const isAlphaNumeric = /^[A-Z0-9]$/.test(lastKey)
  if (!isAlphaNumeric) return false

  // 中间部分只能是修饰键，不能出现多余内容
  for (let i = 0; i < keys.length - 1; i++) {
    if (!modifierKeys.includes(keys[i])) return false
  }

  return true
}

// 按键标准化函数
const normalizeKey = (e: KeyboardEvent) => {
  if (e.key === 'Control') return 'Ctrl'
  if (e.key === 'Alt') return 'Alt'
  if (e.key === 'Shift') return 'Shift'
  if (e.key === 'Meta') return 'Meta'
  if (/^Key[A-Z]$/.test(e.code)) return e.code.replace('Key', '').toUpperCase()
  if (/^Digit[0-9]$/.test(e.code)) return e.code.replace('Digit', '')
  if (/^Numpad[0-9]$/.test(e.code)) return e.code.replace('Numpad', '')
  if (/^[a-zA-Z0-9]$/.test(e.key)) return e.key.toUpperCase()
  return ''
}

// 修改快捷键顺序 'Ctrl'》'Alt'》'Shift'》'Meta'
const normalizeShortcut = (keys: string[]) => {
  const modifiers = keys.filter(k => modifierKeys.includes(k))
    .sort((a, b) => modifierKeys.indexOf(a) - modifierKeys.indexOf(b))
  const mainKeys = keys.filter(k => !modifierKeys.includes(k))
  return [...modifiers, ...mainKeys]
}

// 清除快捷键
const inputRef = ref<HTMLElement | null>(null)
const clearShortcut = () => {
  shortcutKeys.value = []
  displayValue.value = ''
  emits('update:modelValue', '')

  const el = inputRef.value
  if (el) el.focus()
}

onUnmounted(() => {
  stopListening()
})
</script>

<style scoped>
.shortcut-input {
  width: 300px;
  position: relative;
}
.shortcut-input .clearable-btn {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;
  color: #909399;
  font-size: 16px;
  opacity: 0;
  transition: opacity 0.3s;
}
.shortcut-input:hover .clearable-btn {
  opacity: 1;
}
</style>
